/** 请求对象: request
 * 基于 common.js, util.js, api.js, storage.js, axios.js
 */
(function (root, factory) {
  if (typeof exports === 'object') {
    module.exports = factory(require('axios'), require('common'));
  } else if (typeof define === 'function' && define.amd) {
    define(['axios', 'common'], factory);
  } else {
    root.request = factory(root.axios, root.common);
  }
})(this, function (axios, common) {

  /**
   * 获取真实请求url
   * @param {string} url 链接
   * @param {string} type 类型 url, key, domain, all
   * @returns {{domain: string, url: string, key: string}|string}
   */
  function getRealUrl(url, type = 'url') {
    url = url || '';
    let key = '', domain = '';
    for (key in common.domains) {
      if (url.indexOf(key) === 0) {
        domain = common.domains[key].filter((item) => item.selected)[0].url || '';
        url = url.replace(key, domain);
        break;
      }
    }

    const res = { url, key, domain };
    return type === 'all' ? res : res[type];
  }

  const $axios = axios.create({
    // API 请求的默认前缀
    baseURL: '/',
    timeout: 60e3, // 请求超时时间
  });

  /**
   * 请求拦截器
   */
  $axios.interceptors.request.use((config) => {
    config.url = getRealUrl(config.url);
    return config;
  });

  // 响应拦截器
  $axios.interceptors.response.use((response) => {
    return response.data;
  }, (err) => {
    return Promise.reject(err);
  });

  /**
   * 请求方法
   * @param {string} url
   * @param {Object} params
   * @param {Object} options
   * @param {string} method
   * @returns {*}
   */
  function doRequest(url, params = {}, options = {}, method = 'post') {
    const config = Object.assign({
      url,
      method,
      params: ['put', 'post', 'delete', 'patch'].includes(method) ? undefined : params,
      data: ['put', 'post', 'delete', 'patch'].includes(method) ? params : undefined,
    }, options);
    return $axios.request(config);
  }
  const request = {
    get: function (url, params = {}, options = {}) {
      return doRequest(url, params, options, 'get');
    },
    post: function (url, params = {}, options = {}) {
      return doRequest(url, params, options, 'post');
    },
    options: function (url, params = {}, options = {}) {
      return doRequest(url, params, options, 'options');
    },
    cancelAllRequest: function() {
      const cancelFunctions = globalOptions.cancelFunctions;
      cancelFunctions.forEach((cancelFunc) => {
        if (typeof cancelFunc === 'function') {
          cancelFunc();
        }
      });
      globalOptions.cancelFunctions = [];
    },
  };

  // 暴露方法
  window.request = request;
  return request;
});
